package de.bloxel.world;

import java.util.Collection;

import com.jme3.bounding.BoundingBox;
import com.jme3.math.Vector3f;

import de.bloxel.core.BloxelFactory.BloxelType;

/**
 * @since 0.1.0
 * @author Klaus Hauschild
 */
public interface TerrainChunk {

  /**
   * Add the given {@link TerrainElement} to the chunk. Handling of duplicates etc are implementation specific.
   * 
   * @param aTerrainElement
   *          to add
   */
  void addTerrainElement(TerrainElement aTerrainElement);

  /**
   * Adds the terrain element.
   * 
   * @param targetPosition
   *          the target position
   * @param theBoxelType
   *          the boxel type
   * 
   * @deprecated a terrain should be a "Listener" to get informed about add/remove/changed of {@link TerrainElement}S
   */
  @Deprecated
  void addTerrainElement(final Vector3f targetPosition, final BloxelType theBoxelType);

  /**
   * The {@link BoundingBox} of a {@link TerrainChunk} define the volume of the chunk. All {@link TerrainElement}S of
   * the chunk intersects ({@link BoundingBox#intersects(com.jme3.bounding.BoundingVolume)}) the chunk.
   * 
   * @return the {@link BoundingBox} of the chunk
   */
  BoundingBox getBoundingBox();

  /**
   * @return the center of the {@link TerrainChunk}, all methods with {@link Vector3f} parameters are relative to this
   *         location
   */
  Vector3f getCenter();

  /**
   * Gets the number of elements.
   * 
   * @return the number of elements
   */
  int getNumberOfElements();

  /**
   * @return all elements
   */
  Collection<TerrainElement> getTerrainElements();

  /**
   * IDEE: vielleicht noch eine funktion wo man die EventHorizon mit der Anfrage mitgeben kann
   * 
   * Gets the terrain elements.
   * 
   * @param thePlayerLocation
   *          the player location
   * @return the terrain elements
   */
  Collection<TerrainElement> getTerrainElements(final Vector3f thePlayerLocation);

  /**
   * Gets the terrain elements.
   * 
   * @param thePlayerLocation
   *          the player location
   * @param thePlayerDirection
   *          the player direction
   * @return the terrain elements
   */
  Collection<TerrainElement> getTerrainElements(final Vector3f thePlayerLocation, final Vector3f thePlayerDirection);

  /**
   * Removes the terrain element.
   * 
   * @param theCenterVector
   *          the center vector
   * 
   * @deprecated a terrain should be a "Listener" to get informed about add/remove/changed of {@link TerrainElement}S
   */
  @Deprecated
  void removeTerrainElement(final Vector3f theCenterVector);
}